home *** CD-ROM | disk | FTP | other *** search
/ Merciful 2 / Merciful - Disc 2.iso / software / i / imagefxv2.1a.lha / ImageFX / MAGIC / src / mdemo.c < prev    next >
C/C++ Source or Header  |  1996-02-12  |  16KB  |  646 lines

  1. /*
  2.  * MAGIC Image Tester - creates a small public MAGIC image with
  3.  *    a teeny tiny interface.
  4.  *
  5.  * Written by Thomas Krehbiel
  6.  *
  7.  * (This requires 2.0, BTW.)
  8.  *
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <libraries/dos.h>
  14. #include <intuition/intuition.h>
  15. #include <libraries/gadtools.h>
  16. #include <clib/exec_protos.h>
  17. #include <clib/alib_protos.h>
  18. #include <clib/dos_protos.h>
  19. #include <clib/intuition_protos.h>
  20. #include <clib/graphics_protos.h>
  21. #include <clib/gadtools_protos.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <stdarg.h>
  25. #include <stdio.h>
  26.  
  27. #include <magic/magic.h>
  28. #include <magic/magic_protos.h>
  29. #include <magic/magic_pragmas.h>
  30.  
  31. struct Library *IntuitionBase;
  32. struct Library *GfxBase;
  33. struct Library *GadToolsBase;
  34.  
  35. struct MagicBase *MagicBase;
  36.  
  37. UBYTE *planes[4] = { NULL, NULL, NULL, NULL };
  38. struct MagicImage *mi;
  39. struct MagicHandle *mh;
  40. struct MsgPort *hostport;
  41.  
  42.  
  43. void message (char *, ...);
  44.  
  45.  
  46. #define WIDTH     320
  47. #define HEIGHT    200
  48. #define DEPTH     3        /* color */
  49.  
  50. short real_width, real_height;
  51.  
  52. BOOL alloc_planes (UBYTE **planes, int depth)
  53. {
  54.    int i;
  55.  
  56.    for (i = 0; i < depth; i++) planes[i] = NULL;
  57.  
  58.    for (i = 0; i < depth; i++) {
  59.       if (!(planes[i] = AllocMem(WIDTH * HEIGHT, MEMF_CLEAR | MEMF_PUBLIC))) {
  60.          return(FALSE);
  61.       }
  62.    }
  63.  
  64.    /* gradient from black to light violet */
  65.    for (i = 0; i < HEIGHT; i++) {
  66.       memset(planes[0] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
  67.       memset(planes[1] + (WIDTH * i), i * 127 / (HEIGHT-1), WIDTH);
  68.       memset(planes[2] + (WIDTH * i), i * 255 / (HEIGHT-1), WIDTH);
  69.    }
  70.  
  71.    real_width = WIDTH;
  72.    real_height = HEIGHT;
  73.  
  74.    return(TRUE);
  75. }
  76.  
  77. void free_planes (UBYTE **planes, int depth)
  78. {
  79.    int i;
  80.  
  81.    for (i = 0; i < depth; i++) {
  82.       if (planes[i]) {
  83.          FreeMem(planes[i], real_width * real_height);
  84.          planes[i] = NULL;
  85.       }
  86.    }
  87. }
  88.  
  89.  
  90. static
  91. BOOL __saveds PutData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
  92. {
  93.    UBYTE *tagdata;
  94.    LONG byte;
  95.    UBYTE *ptr;
  96.    int i;
  97.    BOOL success = TRUE;
  98.  
  99.    while (*tags != TAG_END) {
  100.       tagdata = (UBYTE *)tags[1];
  101.       switch (*tags) {
  102.          case TAG_IGNORE :
  103.             break;
  104.          case GMI_Red :
  105.             CopyMem(tagdata, planes[0] + (offset * WIDTH), WIDTH * rows);
  106.             break;
  107.          case GMI_Green :
  108.             CopyMem(tagdata, planes[1] + (offset * WIDTH), WIDTH * rows);
  109.             break;
  110.          case GMI_Blue :
  111.             CopyMem(tagdata, planes[2] + (offset * WIDTH), WIDTH * rows);
  112.             break;
  113.          case GMI_RGB :
  114.             byte = offset * WIDTH;
  115.             ptr = (UBYTE *)tagdata;
  116.             for (i = 0; i < WIDTH; i++) {
  117.                planes[0][byte] = *ptr++;
  118.                planes[1][byte] = *ptr++;
  119.                planes[2][byte++] = *ptr++;
  120.             }
  121.             break;
  122.          case GMI_ARGB :
  123.             byte = offset * WIDTH;
  124.             ptr = (UBYTE *)tagdata;
  125.             for (i = 0; i < WIDTH; i++) {
  126.                ptr++;   /* skip alpha */
  127.                planes[0][byte] = *ptr++;
  128.                planes[1][byte] = *ptr++;
  129.                planes[2][byte++] = *ptr++;
  130.             }
  131.             break;
  132.          case GMI_RGBA :   /* V38 only */
  133.             byte = offset * WIDTH;
  134.             ptr = (UBYTE *)tagdata;
  135.             for (i = 0; i < WIDTH; i++) {
  136.                planes[0][byte] = *ptr++;
  137.                planes[1][byte] = *ptr++;
  138.                planes[2][byte++] = *ptr++;
  139.                ptr++;   /* skip alpha */
  140.             }
  141.             break;
  142.          default :
  143.             success = FALSE;     /* unknown data type */
  144.             break;
  145.       }
  146.       tags += 2;
  147.    }
  148.    return(success);
  149. }
  150.  
  151. static
  152. BOOL __saveds GetData (struct MagicImage *pi, LONG offset, LONG rows, LONG *tags)
  153. {
  154.    UBYTE *tagdata;
  155.    LONG byte;
  156.    UBYTE *ptr;
  157.    int i;
  158.    BOOL success = TRUE;
  159.  
  160.    while (*tags != TAG_END) {
  161.       tagdata = (UBYTE *)tags[1];
  162.       switch (*tags) {
  163.          case TAG_IGNORE :
  164.             break;
  165.          case GMI_Red :
  166.             CopyMem(planes[0] + (offset * WIDTH), tagdata, WIDTH * rows);
  167.             break;
  168.          case GMI_Green :
  169.             CopyMem(planes[1] + (offset * WIDTH), tagdata, WIDTH * rows);
  170.             break;
  171.          case GMI_Blue :
  172.             CopyMem(planes[2] + (offset * WIDTH), tagdata, WIDTH * rows);
  173.             break;
  174.          case GMI_RGB :
  175.             byte = offset * WIDTH;
  176.             ptr = (UBYTE *)tagdata;
  177.             for (i = 0; i < WIDTH; i++) {
  178.                *ptr++ = planes[0][byte];
  179.                *ptr++ = planes[1][byte];
  180.                *ptr++ = planes[2][byte++];
  181.             }
  182.             break;
  183.          case GMI_ARGB :
  184.             byte = offset * WIDTH;
  185.             ptr = (UBYTE *)tagdata;
  186.             for (i = 0; i < WIDTH; i++) {
  187.                *ptr++ = 255;
  188.                *ptr++ = planes[0][byte];
  189.                *ptr++ = planes[1][byte];
  190.                *ptr++ = planes[2][byte++];
  191.             }
  192.             break;
  193.          case GMI_RGBA :   /* V38 only */
  194.             byte = offset * WIDTH;
  195.             ptr = (UBYTE *)tagdata;
  196.             for (i = 0; i < WIDTH; i++) {
  197.                *ptr++ = planes[0][byte];
  198.                *ptr++ = planes[1][byte];
  199.                *ptr++ = planes[2][byte++];
  200.                *ptr++ = 255;
  201.             }
  202.             break;
  203.          default :
  204.             success = FALSE;     /* unknown data type */
  205.             break;
  206.       }
  207.       tags += 2;
  208.    }
  209.    return(success);
  210. }
  211.  
  212. BOOL init_magic (void)
  213. {
  214.    if (!(MagicBase = (struct MagicBase *)OpenLibrary(MAGIC_NAME, 0)))
  215.       return(FALSE);
  216.  
  217.    return(TRUE);
  218. }
  219.  
  220. void close_magic (void)
  221. {
  222.    if (mh) {
  223.       CloseMagicImage(mh);
  224.       mh = NULL;
  225.    }
  226.    if (mi) {
  227.       while (!RemMagicImage(mi)) {
  228.          message("Image in use!");
  229.          Delay(50);
  230.       }
  231.       FreeMagicImage(mi);
  232.       free_planes(planes, DEPTH);
  233.       mi = NULL;
  234.    }
  235. }
  236.  
  237. void cleanup_magic (void)
  238. {
  239.    close_magic();
  240.    CloseLibrary((struct Library *)MagicBase);
  241. }
  242.  
  243. void new_magic (void)
  244. {
  245.    close_magic();
  246.  
  247.    if (alloc_planes(planes, DEPTH)) {
  248.       if (mi = AllocMagicImage(AMI_Width, WIDTH,
  249.                                   AMI_Height, HEIGHT,
  250.                                   AMI_Depth, DEPTH,
  251.                                   AMI_Red, planes[0],
  252.                                   AMI_Green, planes[1],
  253.                                   AMI_Blue, planes[2],
  254.                                   AMI_GetDataCode, GetData,
  255.                                   AMI_PutDataCode, PutData,
  256.                                   AMI_OwnerName, "MagicDemo",
  257.                                   TAG_END)) {
  258.          if (AddMagicImage(mi)) {
  259.             /*
  260.              * Even the owner of an image must open it!  Remember to use
  261.              * OMI_OwnerPort instead of OMI_MsgPort.
  262.              */
  263.             if (mh = OpenMagicImage(mi, NULL, OMI_OwnerPort, hostport, TAG_END)) {
  264.                message("Magic image created.");
  265.                return;
  266.             }
  267.             RemMagicImage(mi);
  268.          }
  269.          FreeMagicImage(mi);
  270.       }
  271.       free_planes(planes, DEPTH);
  272.    }
  273.  
  274.    mi = NULL;
  275.    mh = NULL;
  276. }
  277.  
  278. struct NewMenu newMenus[] = {
  279.    { NM_TITLE, "Project",        NULL, 0, 0, 0 },
  280.    { NM_ITEM,  "New",            "N",  0, 0, 0 },
  281.    { NM_ITEM,  "Open...",        "O",  0, 0, 0 },
  282.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  283.    { NM_ITEM,  "Manipulate",     "M",  0, 0, 0 },
  284.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  285.    { NM_ITEM,  "Cycle",          "C",  0, 0, 0 },
  286.    { NM_ITEM,  NM_BARLABEL,      NULL, 0, 0, 0 },
  287.    { NM_ITEM,  "Quit",           "Q",  0, 0, 0 },
  288.    { NM_END }
  289. };
  290.  
  291. struct Window *win;
  292. struct Menu *menus;
  293. APTR vi;
  294.  
  295. BOOL init_gui (void)
  296. {
  297.    struct Screen *scr;
  298.  
  299.    IntuitionBase = OpenLibrary("intuition.library", 37);
  300.    GfxBase = OpenLibrary("graphics.library", 37);
  301.    GadToolsBase = OpenLibrary("gadtools.library", 37);
  302.    /* (yes, I know, but it's just a demo) */
  303.  
  304.    scr = LockPubScreen(NULL);
  305.    if (scr == NULL) return(FALSE);
  306.  
  307.    if (!(win = OpenWindowTags(NULL,
  308.                               WA_Title, "MAGIC Testerosa",
  309.                               WA_InnerWidth, 200,
  310.                               WA_Height, 115 + scr->WBorTop + scr->Font->ta_YSize + 1 + scr->WBorBottom + scr->RastPort.TxHeight + 2,
  311.                               WA_Left, 20,
  312.                               WA_Top, 20,
  313.                               WA_Flags, WFLG_CLOSEGADGET | WFLG_DRAGBAR |
  314.                                           WFLG_DEPTHGADGET |
  315.                                           WFLG_SMART_REFRESH | WFLG_NOCAREREFRESH |
  316.                                           WFLG_ACTIVATE,
  317.                               WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK,
  318.                               WA_NewLookMenus, TRUE,
  319.                               TAG_END))) goto err1;
  320.  
  321.    menus = CreateMenus(newMenus, TAG_END);
  322.    if (menus == NULL) goto err2;
  323.  
  324.    vi = GetVisualInfo(scr, TAG_END);
  325.    if (vi == NULL) goto err3;
  326.  
  327.    LayoutMenus(menus, vi, GTMN_NewLookMenus, TRUE, TAG_END);
  328.  
  329.    SetMenuStrip(win, menus);
  330.  
  331.    UnlockPubScreen(NULL, scr);
  332.  
  333.    return(TRUE);
  334.  
  335. err3:
  336.    FreeMenus(menus);
  337. err2:
  338.    CloseWindow(win);
  339. err1:
  340.    UnlockPubScreen(NULL, scr);
  341.    return(FALSE);
  342. }
  343.  
  344. void cleanup_gui (void)
  345. {
  346.    ClearMenuStrip(win);
  347.    FreeVisualInfo(vi);
  348.    FreeMenus(menus);
  349.    CloseWindow(win);
  350.    CloseLibrary(GadToolsBase);
  351.    CloseLibrary(GfxBase);
  352.    CloseLibrary(IntuitionBase);
  353. }
  354.  
  355. /* 4x4 dispersed dot ordered dither pattern. */
  356. static
  357. UBYTE dith[4][4] = {
  358.     1, 15,  2, 12,
  359.     9,  5, 10,  7,
  360.     3, 13,  0, 14,
  361.    11,  7,  8,  4
  362. };
  363.  
  364. void redraw (void)
  365. {
  366.    UBYTE *outpix;
  367.    UBYTE *rgb;
  368.    int w, h, le, te;
  369.    struct MagicImage *mi;
  370.    struct RastPort temprp;
  371.    struct BitMap tempbm;
  372.    int i, j, x, y;
  373.    short v;
  374.  
  375.    w = win->Width - win->BorderLeft - win->BorderRight - 4;
  376.    h = win->Height - win->BorderTop - win->BorderBottom - 2 - win->RPort->TxHeight - 2;
  377.    le = win->BorderLeft + 2;
  378.    te = win->BorderTop + win->RPort->TxHeight + 3;
  379.  
  380.    if (!mh) {
  381.       SetAPen(win->RPort, 0);
  382.       RectFill(win->RPort, le, te, le + w - 1, te + h - 1);
  383.       return;
  384.    }
  385.  
  386.    mi = mh->Object;
  387.  
  388.    outpix = AllocMem(((w+15)>>4)<<4, MEMF_CLEAR);
  389.    if (outpix == NULL) return;
  390.  
  391.    rgb = AllocMem(mi->Width * 3, MEMF_CLEAR);
  392.    if (rgb == NULL) return;
  393.  
  394.    InitRastPort(&temprp);
  395.    InitBitMap(&tempbm, win->RPort->BitMap->Depth, w, 1);
  396.    temprp.BitMap = &tempbm;
  397.    for (i = 0; i < tempbm.Depth; i++) {
  398.       tempbm.Planes[i] = AllocRaster(w, 1);
  399.       /* ick */
  400.    }
  401.  
  402.    for (j = 0; j < h; j++) {
  403.  
  404.       y = j * (mi->Height-1) / (h-1);
  405.       GetMagicImageData(mh, y, 1, GMI_RGB, rgb, TAG_END);
  406.  
  407.       for (i = 0; i < w; i++) {
  408.          x = (i * (mi->Width-1) / (w-1)) * 3;
  409.          v = ((rgb[x] + rgb[x+1] + rgb[x+2]) / 3) >> 4;
  410.          if (v > dith[j&3][i&3]) outpix[i] = 2;
  411.          else                    outpix[i] = 1;
  412.       }
  413.  
  414.       WritePixelLine8(win->RPort, le, te + j, w, outpix, &temprp);
  415.  
  416.    }
  417.  
  418.    for (i = 0; i < tempbm.Depth; i++) {
  419.       FreeRaster(tempbm.Planes[i], w, 1);
  420.    }
  421.  
  422.    FreeMem(rgb, mi->Width * 3);
  423.    FreeMem(outpix, ((w+15)>>4)<<4);
  424. }
  425.  
  426. struct MagicImage *pick_magic (void)
  427. {
  428.    struct MagicImage *m = NULL;
  429.  
  430.  
  431.    m = PickMagicImage(NULL,
  432.          PMI_ExcludeOwner, "MagicDemo",
  433.          PMI_ShowSize, TRUE,
  434.          PMI_ShowOwner, TRUE,
  435.          TAG_END);
  436.  
  437.    if (m) {
  438.       close_magic();
  439.  
  440.       if (mh = OpenMagicImage(m, NULL, OMI_MsgPort, hostport, TAG_END)) {
  441.          message("Magic Image opened.");
  442.       }
  443.    }
  444.  
  445.    return(m);
  446. }
  447.  
  448. void message (char *txt, ...)
  449. {
  450.    struct RastPort *rp = win->RPort;
  451.    char buf[80];
  452.    va_list va;
  453.  
  454.    va_start(va, txt);
  455.    vsprintf(buf, txt, va);
  456.    va_end(va);
  457.  
  458.    SetAPen(rp, 0);
  459.    SetDrMd(rp, JAM1);
  460.    RectFill(rp,
  461.       win->BorderLeft,
  462.       win->BorderTop,
  463.       win->Width - win->BorderRight - 1,
  464.       win->BorderTop + rp->TxHeight);
  465.  
  466.    SetAPen(rp, 1);
  467.    SetDrMd(rp, JAM1);
  468.    Move(rp, win->BorderLeft + 2, win->BorderTop + rp->TxBaseline + 1);
  469.    Text(rp, buf, strlen(buf));
  470. }
  471.  
  472.  
  473. void __regargs negative (UBYTE *data, int width)
  474. {
  475.    while (width--) {
  476.       *data = 255 - *data;
  477.       data++;
  478.    }
  479. }
  480.  
  481. /* do something interesting to the image buffer.  yeah, right */
  482.  
  483. void manipulate (void)
  484. {
  485.    struct MagicImage *mi;
  486.    UBYTE *buf;
  487.    int j, p;
  488.    LONG tag[3] = { GMI_Red, GMI_Green, GMI_Blue };
  489.  
  490.    if (mh) {
  491.       if (!AttemptLockMagicImage(mh, LMI_Write)) {
  492.          message("Image is locked.");
  493.          return;
  494.       }
  495.       mi = mh->Object;
  496.       if (buf = AllocMem(mi->Width, MEMF_CLEAR)) {
  497.  
  498.          message("Processing...");
  499.          if (!mi) SaveMagicImage(mh, 0, 0, mi->Width, mi->Height);
  500.          for (j = 0; j < mi->Height; j++) {
  501.             for (p = 0; p < mi->Depth; p++) {
  502.                GetMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
  503.                negative(buf, mi->Width);
  504.                PutMagicImageData(mh, j, 1, tag[p], buf, TAG_END);
  505.             }
  506.          }
  507.          RedrawMagicImage(mh, 0, 0, mi->Width, mi->Height);
  508.          message("Image manipulated.");
  509.  
  510.          FreeMem(buf, mi->Width);
  511.       }
  512.  
  513.       UnlockMagicImage(mh);
  514.    }
  515. }
  516.  
  517. void halve (void)
  518. {
  519. #if 0
  520.    UBYTE *newplane;
  521.    int neww, newh;
  522.  
  523.    if (mi) {
  524.       neww = real_width / 2;
  525.       newh = real_height / 2;
  526.       for (p = 0; p < 3; p++) {
  527.          newplane = AllocMem(neww * newh, MEMF_CLEAR);
  528.          if (newplane == NULL) break;  /* crash city */
  529.          /* FINISH THIS! */
  530.       }
  531.    }
  532.    else {
  533.       message("Can't resize foreign images.");
  534.    }
  535. #endif
  536. }
  537.  
  538.  
  539. void event_loop (void)
  540. {
  541.    struct IntuiMessage *msg;
  542.    struct MagicMessage *mmsg;
  543.    ULONG wsig, hsig, sigs;
  544.    BOOL quit = FALSE;
  545.    int oldpri;
  546.  
  547.    message("Standing by...");
  548.  
  549.    wsig = 1 << win->UserPort->mp_SigBit;
  550.    hsig = 1 << hostport->mp_SigBit;
  551.  
  552.    while (!quit) {
  553.  
  554.       sigs = Wait(wsig | hsig);
  555.  
  556.       if (sigs & wsig) {
  557.          while (msg = (struct IntuiMessage *)GetMsg(win->UserPort)) {
  558.             switch(msg->Class) {
  559.                case IDCMP_CLOSEWINDOW :
  560.                   quit = TRUE;
  561.                   break;
  562.                case IDCMP_MENUPICK :
  563.                   switch(ITEMNUM(msg->Code)) {
  564.                      case 0 : new_magic(); redraw(); break;
  565.                      case 1 : pick_magic(); redraw(); break;
  566.                      case 3 : manipulate(); redraw(); break;
  567.                      case 5 : if (mh) CycleMagicImage(mh); break;
  568.                      case 7 : quit = TRUE; break;
  569.                      default: break;
  570.                   }
  571.                   break;
  572.                default :
  573.                   break;
  574.             }
  575.             ReplyMsg((struct Message *)msg);
  576.          }
  577.       }
  578.  
  579.       if (sigs & hsig) {
  580.          while (mmsg = (struct MagicMessage *)GetMsg(hostport)) {
  581.             mmsg->Result = 0;
  582.             switch(mmsg->Action) {
  583.                case MMSG_UPDATE :
  584.                   message("Update");
  585.                   break;
  586.                case MMSG_REDRAW :
  587.                   message("Redraw %ld %ld %ld %ld",
  588.                      mmsg->Args[0], mmsg->Args[1], mmsg->Args[2], mmsg->Args[3]);
  589.                   oldpri = SetTaskPri(FindTask(NULL), -1);
  590.                   redraw();
  591.                   SetTaskPri(FindTask(NULL), oldpri);
  592.                   break;
  593.                case MMSG_TOFRONT :
  594.                   message("To Front");
  595.                   ScreenToFront(win->WScreen);
  596.                   WindowToFront(win);
  597.                   ActivateWindow(win);
  598.                   break;
  599.                case MMSG_SAVEUNDO :
  600.                   message("Save Undo");
  601.                   break;
  602.                case MMSG_RESTOREUNDO :
  603.                   message("Restore Undo");
  604.                   break;
  605.                case MMSG_CLOSE :
  606.                   message("Hit The Road");
  607.                   close_magic();
  608.                   redraw();
  609.                   break;
  610.                default :
  611.                   mmsg->Result = -1;
  612.                   break;
  613.             }
  614.             ReplyMsg((struct Message *)mmsg);
  615.          }
  616.       }
  617.  
  618.       if (quit) {
  619.          if (mi && mi->OpenCount > 1) {
  620.             message("No way - image in use.");
  621.             quit = FALSE;
  622.          }
  623.       }
  624.  
  625.    }
  626. }
  627.  
  628.  
  629. void main (int argc, char **argv)
  630. {
  631.    struct Task *task = FindTask(NULL);
  632.  
  633.    task->tc_Node.ln_Name = "Magic Demo";
  634.  
  635.    if (hostport = CreatePort(NULL, 0)) {
  636.       if (init_gui()) {
  637.          if (init_magic()) {
  638.             event_loop();
  639.             cleanup_magic();
  640.          }
  641.          cleanup_gui();
  642.       }
  643.       DeletePort(hostport);
  644.    }
  645. }
  646.